package com.cqemme.messageservice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.cqemme.comm.po.NoteMessage;
import com.cqemme.comm.po.Result;
import com.cqemme.comm.utils.JackSonUtils;
import com.cqemme.comm.utils.ResultCodeMsg;
import com.cqemme.messageservice.component.SendSms;
import com.cqemme.messageservice.service.NoteService;
import com.cqemme.messageservice.util.EmptyChecker;
import com.cqemme.messageservice.util.JedisUtil;
import com.cqemme.messageservice.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class NoteServiceImpl implements NoteService {

    @Autowired
    private JedisUtil jedisUtil;

    @Autowired
    private SendSms sendSms;

    @Resource(name = "restTemplate")
    private RestTemplate restTemplate;

    @Value("${node.api.note.save}")
    private String noteSaveUrl;

    @Override
    public void sendNote(NoteMessage noteMap) {
        switch (noteMap.getType()) {
            case EARLY_WARNING:
                //校安链预警通知
                goAli(noteMap);
                break;
            case IDENTITY_VERIFICATION:
                //身份验证验证码
            case LOGIN_SUMMIT:
                //登录确认验证码
            case LOGIN_ERROR:
                //登录异常验证码
            case UPDATE_PASSWORD:
                //修改密码验证码
            case UPDATE_INFO:
                //信息变更验证码
            case REGISET:
                //用户注册验证码
                vaSend(noteMap);
                break;
            default:
        }
    }

    /**
     * 验证是否发短信
     * @param noteMap
     */
    public void vaSend(NoteMessage noteMap){
        String exStr = noteMap.getType().getTemplateCode() + noteMap.getMobile() + "num";
        if (jedisUtil.exists(exStr)) {
            if (Integer.parseInt(jedisUtil.get(exStr)) >= 3) {
                return;
            }
        }
        String mStr = noteMap.getType().getTemplateCode() + noteMap.getMobile();
        if (!jedisUtil.exists(mStr)) {
            //发短信
            goAli(noteMap);
        } else {
            String dStr = jedisUtil.get(mStr);
            Map cacheNote = JackSonUtils.strToBean(dStr, Map.class);
            long nowTime = System.currentTimeMillis();
            int s = String.valueOf(nowTime).length() > 10 ? 1000 : 1;
            if ((nowTime - Long.parseLong(cacheNote.get("time") + "")) / s >= 60) {
                goAli(noteMap);
            }
        }
    }

    /**
     * 验证短信码
     *
     * @param note
     * @return
     */
    @Override
    public Result validatorNote(NoteMessage note) {
        Result result = new Result();
        String msg = null;
        int code = ResultCodeMsg.CODE_204;
        String mStr = note.getType().getTemplateCode() + note.getMobile();
        if (!jedisUtil.exists(mStr)) {
            msg = "验证码已过期";
        } else {
            Map cacheNote = JackSonUtils.strToBean(jedisUtil.get(mStr), Map.class);
            if (note.getCode().equals(cacheNote.get("code") + "")) {
                result.setStatusCode(ResultCodeMsg.CODE_200);
                return result;
            }
            msg = "验证码不正确";
        }
        result.setMessage(msg);
        result.setStatusCode(code);
        return result;
    }

    /**
     * 调阿里发短信
     */
    public void goAli(NoteMessage noteMap) {
        String sendMobile = noteMap.getMobile();
        //组装发送短信数据
        Map<String, Object> par = new HashMap<>();
        par.put("mobile", sendMobile);
        par.put("siginName", noteMap.getType().getSignName());
        par.put("templateCode", noteMap.getType().getTemplateCode());
        if (EmptyChecker.notEmpty(noteMap.getOutId())) {
            par.put("outId", noteMap.getOutId());
        }
        Map<String, Object> sendCodeMap = new HashMap<>();
        try {
            switch (noteMap.getType()) {
                case EARLY_WARNING:
                    //校安链预警通知
                    par.put("par", noteMap.getExData());
                    sendSms.send(par);
                    Map<String,Object> mongo=new HashMap<>();
                    mongo.put("mobile", sendMobile);
                    mongo.put("type", JSONObject.toJSONString(noteMap.getType()));
                    restTemplate.postForObject(noteSaveUrl, mongo, Map.class);
                    break;
                case IDENTITY_VERIFICATION:
                    //身份验证验证码
                case LOGIN_SUMMIT:
                    //登录确认验证码
                case LOGIN_ERROR:
                    //登录异常验证码
                case UPDATE_PASSWORD:
                    //修改密码验证码
                case UPDATE_INFO:
                    //信息变更验证码
                case REGISET:
                    String code = TimeUtil.getRandomCode(6);
                    sendCodeMap.put("code", code);
                    par.put("par", sendCodeMap);
                    sendSms.send(par);
                    saveRegisetRedis(noteMap,code);
                    break;
                default:
            }
        } catch (Exception e) {
            log.error("短信发送失败", e);
        }
    }

    /**
     * 注册发短信后存redis方便验证
     * @param noteMap
     * @param code
     */
    public void saveRegisetRedis(NoteMessage noteMap,String code){
        String sendMobile = noteMap.getMobile();
        String sendType=noteMap.getType().getTemplateCode();
        //存本次发送信息进redis
        Map<String, Object> cache = new HashMap<>();
        cache.put("time", System.currentTimeMillis());
        cache.put("code", code);
        String mStr=sendType + sendMobile;
        jedisUtil.set(mStr, JackSonUtils.beanToString(cache));
        jedisUtil.expire(mStr, 300);

        //存同一类型同一手机每天只能发送三次
        String exStr = mStr + "num";
        if (jedisUtil.exists(exStr)) {
            int sendCount = Integer.parseInt(jedisUtil.get(exStr)) + 1;
            jedisUtil.set(exStr, sendCount + "");
        } else {
            jedisUtil.set(exStr, "1");
        }
        jedisUtil.expire(exStr, TimeUtil.getSecondsNextEarlyMorning());

        //存发短信记录进mongodb
        cache.put("mobile", sendMobile);
        cache.put("type", JSONObject.toJSONString(noteMap.getType()));
        restTemplate.postForObject(noteSaveUrl, cache, Map.class);
    }

}
